package com.systop.common.modules.security.user.model;

import java.io.Serializable;
import java.util.Arrays;
import java.util.Date;
import java.util.HashSet;
import java.util.Set;

import javax.persistence.Column;
import javax.persistence.Entity;
import javax.persistence.FetchType;
import javax.persistence.GeneratedValue;
import javax.persistence.Id;
import javax.persistence.JoinColumn;
import javax.persistence.JoinTable;
import javax.persistence.ManyToMany;
import javax.persistence.ManyToOne;
import javax.persistence.Table;
import javax.persistence.Transient;

import org.acegisecurity.GrantedAuthority;
import org.acegisecurity.userdetails.UserDetails;
import org.apache.commons.lang.StringUtils;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.hibernate.annotations.GenericGenerator;

import com.systop.common.modules.dept.model.Dept;
import com.systop.core.Constants;
import com.systop.core.model.BaseModel;
import com.systop.core.util.DateUtil;

/**
 * 用户表 The persistent class for the users database table.
 * 
 * @author BEA Workshop
 */
@SuppressWarnings("serial")
@Entity
@Table(name = "users", uniqueConstraints = {})
public class User extends BaseModel implements UserDetails, Serializable {

	/** Log */
	private static Log log = LogFactory.getLog(User.class);

	/** 主键 */
	private Integer id;

	/** 登录ID */
	private String loginId;

	/** 密码 */
	private String password;

	/** 注册时间 */
	private Date createTime;

	/** 姓名 */
	private String name;
	
	/** 性别 */
	private String sex;

	/** 出生日期 */
	private Date birthday;

	/** 手机 */
	private String mobile;

	/** 电话 */
	private String phone;
	
	/** 身份证号 */
	private String idCard;

	/** 电子邮件 */
	private String email;
	
	/** 银行帐号 */
	private String bank;
	
	/** 银行帐号 */
	private String bankAccount;

	/** 用户描述 */
	private String descn;

	/** 状态 */
	private String status;
	
	/** 是否系统用户 */
	private String isSys;

	/** 用户类别 */
	private String type;

	/** 用戶是否在线，0（缺省）表示不在线，1表示在线。  */
	private String online;
	
	/** 最后登录IP */
	private String lastLoginIp;

	/** 最后登录时间 */
	private Date lastLoginTime;

	/** 登录次数 */
	private Integer loginTimes;

	/** 所属部门 */
	private Dept dept;
	
	/** 所具有的角色 */
	private Set<Role> roles = new HashSet<Role>(0);

	/** 缺省构造器 */
	public User() {
	}

	@Id
	@GeneratedValue(generator = "hibseq")
	@GenericGenerator(name = "hibseq", strategy = "hilo")
	@Column(name = "id", nullable = false)
	public Integer getId() {
		return this.id;
	}

	public void setId(Integer id) {
		this.id = id;
	}
	
	@Column(name = "login_id")
	public String getLoginId() {
		return this.loginId;
	}

	public void setLoginId(String loginId) {
		this.loginId = loginId;
	}
	
	public String getPassword() {
		return this.password;
	}

	public void setPassword(String password) {
		this.password = password;
	}

	public Date getCreateTime() {
		return createTime;
	}

	public void setCreateTime(Date createTime) {
		this.createTime = createTime;
	}

	public String getName() {
		return name;
	}

	public void setName(String name) {
		this.name = name;
	}
	
	public String getSex() {
		return sex;
	}

	public void setSex(String sex) {
		this.sex = sex;
	}

	public Date getBirthday() {
		return birthday;
	}

	public void setBirthday(Date birthday) {
		this.birthday = birthday;
	}

	public String getMobile() {
		return mobile;
	}

	public void setMobile(String mobile) {
		this.mobile = mobile;
	}
	
	public String getPhone() {
		return phone;
	}

	public void setPhone(String phone) {
		this.phone = phone;
	}
	
	@Column(name = "id_card")
	public String getIdCard() {
		return idCard;
	}

	public void setIdCard(String idCard) {
		this.idCard = idCard;
	}

	public String getEmail() {
		return this.email;
	}
	
	public void setEmail(String email) {
		this.email = email;
	}

	public String getBank() {
		return bank;
	}

	public void setBank(String bank) {
		this.bank = bank;
	}

	public String getBankAccount() {
		return bankAccount;
	}

	public void setBankAccount(String bankAccount) {
		this.bankAccount = bankAccount;
	}

	public String getDescn() {
		return this.descn;
	}

	public void setDescn(String descn) {
		this.descn = descn;
	}
	
	@Column(columnDefinition = "char(1) default '1'")
	public String getStatus() {
		return this.status;
	}

	public void setStatus(String status) {
		this.status = status;
	}
	
	@Column(name = "is_sys", columnDefinition = "char(1) default '0'")
	public String getIsSys() {
		return isSys;
	}
	
	public void setIsSys(String isSys) {
		this.isSys = isSys;
	}

	@Column(name = "type", length = 20)
	public String getType() {
		return type;
	}

	public void setType(String type) {
		this.type = type;
	}

	@Column(name = "is_online", columnDefinition = "char(1) default '0'")
	public String getOnline() {
		return online;
	}
	
	public void setOnline(String online) {
		this.online = online;
	}

	@Column(name = "last_login_ip")
	public String getLastLoginIp() {
		return this.lastLoginIp;
	}

	public void setLastLoginIp(String lastLoginIp) {
		this.lastLoginIp = lastLoginIp;
	}

	@Column(name = "last_login_time")
	public Date getLastLoginTime() {
		return this.lastLoginTime;
	}

	public void setLastLoginTime(Date lastLoginTime) {
		this.lastLoginTime = lastLoginTime;
	}

	@Transient
	public String getLastLoginTimeStr() {
		return DateUtil.convertDateToString(lastLoginTime, "yyyy-MM-dd HH:mm");
	}

	@Column(name = "login_times")
	public Integer getLoginTimes() {
		return this.loginTimes;
	}

	public void setLoginTimes(Integer loginTimes) {
		this.loginTimes = loginTimes;
	}

	@ManyToOne(cascade = {}, fetch = FetchType.LAZY)
	@JoinColumn(name = "dept_id")
	public Dept getDept() {
		return this.dept;
	}

	public void setDept(Dept dept) {
		this.dept = dept;
	}

	@ManyToMany(targetEntity = Role.class, cascade = {}, fetch = FetchType.LAZY)
	@JoinTable(name = "user_role", joinColumns = { @JoinColumn(name = "user_id") }, inverseJoinColumns = { @JoinColumn(name = "role_id") })
	public Set<Role> getRoles() {
		return this.roles;
	}

	public void setRoles(Set<Role> roles) {
		this.roles = roles;
	}


	/** 用户所具有的权限，可用通过角色-权限对应关系得到  */
	private transient GrantedAuthority[] authorities;

	/** @see {@link UserDetails#getAuthorities()} */
	@Transient
	public GrantedAuthority[] getAuthorities() {
		return this.authorities;
	}

	/** @param authorities the authorities to set */
	public void setAuthorities(GrantedAuthority[] authorities) {
		log.info("Set GrantedAuthorities :" + Arrays.toString(authorities));
		this.authorities = authorities;
	}

	/** @see {@link UserDetails#getUsername()} */
	@Transient
	public String getUsername() {
		return this.loginId;
	}

	/** @see {@link UserDetails#isAccountNonExpired()} */
	@Transient
	public boolean isAccountNonExpired() {
		return true;
	}

	/** @see {@link UserDetails#isAccountNonLocked()} */
	@Transient
	public boolean isAccountNonLocked() {
		return true;
	}

	/** {@link UserDetails#isCredentialsNonExpired()} */
	@Transient
	public boolean isCredentialsNonExpired() {
		return true;
	}

	/**  {@link UserDetails#isEnabled()} */
	@Transient
	public boolean isEnabled() {
		return StringUtils.equalsIgnoreCase(status, Constants.STATUS_AVAILABLE);
	}

	/** 是否有角色  */
	@Transient
	public boolean getHasRoles() {
		return roles.size() > 0;
	}
}